/**
 * accesss_token特点：
 *  1.唯一的凭证；
 *  2.有效时间为2小时，需提前5分钟请求；
 *  3.接口权限每天2000次。
 
    请求地址：
    https请求方式: GET https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
    (需要用到APPID，APPSECRET)
    请求方式：
    GET
    
    设计方式：

    查看本有无access_token文件（readAccessToken），
    1.有，
        判断是否过期(isAccessToken)： 
            过期了：重新通过url, get请求 (getAccessToken),保存并覆盖本地access_token文件(saveAccessToken) 
            没有过期：请求本地文件
    2.没有，
        直接通过url进行请求(getAccessToken)，并保存access_token(本地文件)(saveAccessToken)。       
*/
//只需引入request-promise-native
const rq = require('request-promise-native')
// 引入fs模块
const {
    writeFile,
    readFile
} = require('fs')
// 引入config
const config = require('../config/index.js')



//定义类 获取access_token
class Wechat {
    constructor() {


    }

    /**
     * 获取access_token的方法
     */
    getAccessToken() {

        //定义请求地址
        const url = `https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${config.appId}&secret=${config.appsecret} `

        // 发送请求
        /**
         * request
         * request-promise-native 返回值是一个promise对象
         */
        return new Promise((resolve, reject) => {
            rq({
                    method: 'GET',
                    url,
                    json: true
                })
                .then((res) => {
                    console.log(res)
                    /**
                     * {access_token: '45_t7kD1kfV-Q6uxeXpgQg2o6Bf4tnEtJMB8HxADRq…1KAFWoleA0kGxCpHypo3PLqU5VGKrhiKJAdAHATSJ', expires_in: 7200}
                     */

                    // 设置access_token过期时间,在2小时到来的提前5分钟设置过期
                    res.expires_in = Date.now() + (res.expires_in - 300) * 1000
                    // 将promise对象状态改成成功状态 
                    resolve(res);
                })
                .catch((err) => {
                    console.log(err)
                    // 将promise对象状态改成失败状态 
                    reject('getAccessToken方法出错了' + err)
                })
        })
    }
    /**
     * 保存access_token的方法
     */
    saveAccessToken(accessToken) {
        // 将获取到的access_token对象转换为JOSN字符串
        accessToken = JSON.stringify(accessToken)

        return new Promise((resolve, reject) => {
            // 将access_token保存为一个文件（用到fs模块）
            writeFile('./accessToken.txt', accessToken, (err) => {
                if (!err) {
                    console.log('文件保存好了')
                    resolve()
                } else {
                    reject('saveAccessToken方法出错了' + err)
                }
            })
        })
    }

    /**
     * 读取access_token的方法
     */
    readAccessToken() {

        return new Promise((resolve, reject) => {
            // 读取本地文件的access_token
            readFile('./accessToken.txt', (err, data) => {
                if (!err) {
                    data = JSON.parse(data)
                    resolve(data)
                    console.log('文件读取成功------')
                } else {
                    reject('readAccessToken方法出错了' + err)
                }
            })
        })
    }
    /**
     *  判断access_token是否有效
     */
    isAccessToken(data) {
        return new Promise((resolve, reject) => {
            if (!data && !data.access_token && !data.expires_in) {
                //代表access_token无效
                return false
            }
            //检测access_token是否在有效期内
            /*1️⃣
            if(data.expires_in < Date.now()){
                //过期了
                return false
            }else{
                //在有效期内
                return true
            }
            */
            /*2️⃣
            return data.expires_in < Date.now()?false:true
            */
            //3️⃣
            console.log(data.expires_in,Date.now())
            return data.expires_in > Date.now()
            
        })
    }
}




// 模拟测试
const w = new Wechat()

new Promise((resolve, reject) => {
    //先读取
    w.readAccessToken()
        //在判断有无本地文件
        //1.本地有
        .then(res => {
            console.log('本地有')
            //在判断
            if (w.isAccessToken(res)) {
                //1.access_token有效没过期
                resolve(res)
            } else {
                //2.发送请求获取access_token
                w.getAccessToken()
                    .then(res => {
                        //请求到并保存本地为本地access_token文件
                        w.saveAccessToken(res)
                            .then(res => {
                                resolve(res)
                            })
                    })
            }
        })
        .catch(err => {
            //2.本地无access_token文件
            //发送请求获取access_token
            console.log('本地无')
            w.getAccessToken()
                .then(res => {
                    //请求到并保存本地为本地access_token文件
                    w.saveAccessToken(res)
                        .then(() => {
                            resolve(res)
                        
                        })
                })
        })
})
.then(res=>{
    console.log(res)
})
.catch(err=>{
    console.log(err)
})